<script setup lang="ts">
  import { computed, PropType, ref } from 'vue'
  import { UploadFile, UploadRawFile } from 'element-plus'
  import { HMessageBox } from '@/components/common/message'
  import VideoPreviewUrl from '@/assets/image/pages/order/new/video.png'
  import VideoPreview from '@/views/return-factory/repair/form/components/custom-info/VideoPreview.vue'

  defineOptions({
    name: 'OrderCustomFormFileUpload',
  })

  const props = defineProps({
    size: {
      type: Number,
      default: () => 50,
    },
    num: {
      type: Number,
      default: () => 5,
    },
    uploadType: {
      type: String as PropType<'picture' | 'video'>,
      default: () => 'picture',
    },
    disabled: {
      type: Boolean,
      default: () => false,
    },
  })

  // 文件上传类型
  const fileUploadType = computed(() => {
    if (props.uploadType === 'picture') {
      return '.jpg,.png,.jpeg,.gif'
    }
    return '.mp4,.m3u8,.avi'
  })

  // 文件列表
  const fileList = defineModel<Array<{ file: UploadRawFile; url: string }>>('modelValue', {
    default: [],
  })

  // 正在预览的文件的索引
  const currentPreviewVideoIndex = ref(-1)

  // 视频预览弹窗显示状态
  const videoPreviewModalVisible = ref(false)

  /**
   * 文件上传事件
   * @param {UploadFile} uploadFile - 上传的文件对象
   */
  const handleUploadFile = (uploadFile: UploadFile) => {
    if (fileList.value.length >= props.num) {
      HMessageBox.error(`最多上传${props.num}个文件`)
      return
    }

    if (uploadFile.raw.size / 1024 / 1024 > props.size) {
      HMessageBox.error(`文件不能大于${props.size}MB`)
      return
    }

    if (props.uploadType === 'picture' && !uploadFile.raw.type.includes('image')) {
      HMessageBox.error('只能上传图片')
      return
    }

    if (props.uploadType === 'video' && !uploadFile.raw.type.includes('video')) {
      HMessageBox.error('只能上传视频')
      return
    }

    fileList.value.push({
      file: uploadFile.raw,
      url: URL.createObjectURL(uploadFile.raw),
    })
  }

  /**
   * 文件删除事件
   * @param {number} index - 文件索引
   */
  const handleFileDel = (index: number) => {
    fileList.value.splice(index, 1)
  }

  /**
   * 视频预览事件
   * @param {number} index - 文件索引
   */
  const handleVideoPreview = (index: number) => {
    currentPreviewVideoIndex.value = index
    videoPreviewModalVisible.value = true
  }
</script>

<template>
  <div class="order-custom-form-file-list">
    <el-upload
      v-if="fileList.length < props.num"
      multiple
      :auto-upload="false"
      drag
      :accept="fileUploadType"
      :on-change="handleUploadFile"
      :show-file-list="false"
      :disabled="props.disabled"
    >
      <el-icon :size="24" color="#007cff">
        <UploadFilled />
      </el-icon>
    </el-upload>
    <template v-for="(file, fileIndex) in fileList" :key="fileIndex">
      <h-image
        v-if="props.uploadType === 'picture'"
        :src="file.url"
        :padding="2"
        :preview-src-list="fileList.map((item) => item.url)"
        :width="80"
        :height="50"
        @del="handleFileDel(fileIndex)"
      />
      <h-image
        v-else
        :src="VideoPreviewUrl"
        :padding="2"
        :width="80"
        :is-show-img-preview="false"
        :height="50"
        @del="handleFileDel(fileIndex)"
        @preview="handleVideoPreview(fileIndex)"
      />
    </template>

    <video-preview
      v-model:visible="videoPreviewModalVisible"
      :initial-index="currentPreviewVideoIndex"
      :video-list="fileList.map((item) => item.url)"
    />
  </div>
</template>

<style scoped lang="scss">
  .order-custom-form-file-list {
    display: flex;
    flex-wrap: wrap;

    :deep(.el-upload) {
      width: 80px;
      height: 50px;

      .el-upload-dragger {
        display: flex;
        align-items: center;
        column-gap: 5px;
        width: 100%;
        height: 100%;
        padding: 0;
        background: none;
        justify-content: center;
      }
    }
  }
</style>
